登录token失效后,自动更新

MuYan2021-08-27web
  • 在开发时总会遇到用户登录信息失效,需要重登操作,如是在用户操作时,需要重登,很影响用户体验

可参考的解决方法:

  1. 后端于用户操作时延长登录时效(存在弊端)。
  2. 后端取消登录时效。
  3. 前端进行自动重登。

这里主要讲解第 3 个方法,讲解示例 axios

参考文档:封装 Axios 封装(拦截器)

要点:

  • 缓存 token,建议使用依赖库 js-cookie 自行封装,此处为了精简代码使用 localStorage。
  • isUpdate 标识更新 Token 中,作用:1.防止重复更新。2.用于多并发请求时暂存后续请求队列的标识。
  • response.config 是原请求的配置,config 内 已经带上了 baseUrl,因此重新请求时需要去掉,同时更新 token。
  • 更新 token 后重新请求 token 失效时的请求。

示例

import axios from "axios";
import qs from 'qs';

const tokenName = "token";

// 从 localStorage 获取缓存的 token
const getToken = () => {
  return window.localStorage.getItem(tokenName);
};

// 给实例添加一个 setToken 方法,用于登录后将最新 token 动态添加到 header,同时将 token 缓存
instance.setToken = (token) => {
  instance.defaults.headers[tokenName] = token;
  window.localStorage.setItem(tokenName, token);
};

const updateTokenFun = () => {
  // instance是已创建的axios实例
  return instance.post("更新登录信息的地址url");
};

// 重置 config 信息
const resetConfig = (config) => {
    config.baseURL = '';
    config.headers[tokenName] = token;
}

const baseURL = "请求地址";

// 创建一个axios实例
const instance = axios.create({
  baseURL,
  timeout: 500000 // 请求超时时间(毫秒)
  headers: {
    "Content-Type": "application/json",
    token: getToken(),
  },
});

// 更新状态标记
let isUpdate = false;

// 待请求队列
let requests = [];

// 响应请求的拦截器
instance.interceptors.response.use(
  (response) => {
    // 对回调数据进行处理
    const { code } = response.data;
    // 定义token 失效时的 code 值,需和后端沟通
    if (code === 10086) {
      const config = response.config;
      // 更新用户信息
      if (!isUpdate) {
        isUpdate = true;
        return updateTokenFun().then((res) => {
            const { token } = res.data;
            instance.setToken(token);

            resetConfig(config)
            // 用户信息已刷新,将更新中挂起的队列进行遍历请求
            requests.forEach((cb) => cb(token));
            // 清除Promise队列
            requests = [];
            // * 继续当前请求
            return instance(config);
        }).catch((res) => {
            console.error("更新失败", res);
            // 更新失败,重置页面至首页
            window.location.href = "/";
        }).finally(() => {
            isUpdate = false;
        });
      } else {
        // 用户信息更新中,通过Promise挂起后续请求,等待更新后遍历请求
        return new Promise((resolve) => {
          requests.push((token) => {
            resetConfig(config)
            resolve(instance(config));
          });
        });
      }
    }
    return response;
}, (error) => {
    // 处理请求回调错误
    return Promise.reject(error);
});

export default instance;
上次更新 2026/6/23 11:49:15
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8
本页目录